package com.derbysoft.lowcostadapter.schedule.sync.impl;

import com.derbysoft.lowcostadapter.commons.exception.SystemException;
import com.derbysoft.lowcostadapter.commons.repository.SystemVariableRepository;
import com.derbysoft.lowcostadapter.commons.utils.DateTimeUtils;
import com.derbysoft.lowcostadapter.dswitch2.service.helper.Constant;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Date;

public abstract class SyncFromFileServiceBase extends SyncServiceBase {
    private static final Logger logger = LoggerFactory.getLogger(SyncFromFileServiceBase.class);
    protected SystemVariableRepository systemVariableRepository;

    @Override
    protected void syncInternal() {
        SyncFile syncFile = getSyncFile();
        if (syncFile == null || StringUtils.isBlank(syncFile.getName())) {
            return;
        }
        synchronized (getFileName().intern()) {
            if (doSync()) {
                updateStatus();
            } else {
                logger.info("Sync encounter an error for {}", getClass().getSimpleName());
            }
        }
    }

    private SyncFile getSyncFile() {
        return SyncFile.fromJson(systemVariableRepository.getValue(getConfigVariableName()));
    }

    protected abstract boolean doSync();

    protected abstract String getTimestampVariableName();

    protected abstract String getConfigVariableName();

    private void updateStatus() {
        try {
            Date lastModified = new Date(getFile().lastModified());
            systemVariableRepository.update(getTimestampVariableName(), DateTimeUtils.formatDateTime(lastModified));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    private File getFile() {
        try {
            String localFolder = systemVariableRepository.getValue(Constant.LOCAL_FOLDER);
            if (localFolder == null) {
                throw new SystemException(String.format("system config not found:[%s] !!", Constant.LOCAL_FOLDER));
            }
            File file = new File(localFolder + File.separator + getFileName());
            if (!file.exists()) {
                throw new FileNotFoundException(localFolder + File.separator + getFileName());
            }
            return file;
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        }
        return null;
    }

    private String getFileName() {
        SyncFile syncFile = SyncFile.fromJson(systemVariableRepository.getValue(getConfigVariableName()));
        if (syncFile != null) {
            return syncFile.getName();
        }
        return null;
    }

    protected InputStream getFileInputStream() {
        try {
            File file = getFile();
            if (file != null) {
                return new FileInputStream(file);
            }
        } catch (FileNotFoundException e) {
            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            logger.error(writer.toString());
        }
        return null;
    }

    public void setSystemVariableRepository(SystemVariableRepository systemVariableRepository) {
        this.systemVariableRepository = systemVariableRepository;
    }
}
